package com.example.w.service.impl;

import com.example.w.common.exception.SystemException;
import com.example.w.common.pojo.MenuItem;
import com.example.w.common.pojo.TypeNum;
import com.example.w.common.util.Utils;
import com.example.w.dao.MenuItemDao;
import com.example.w.service.MenuItemService;
import org.apache.ibatis.reflection.ArrayUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.List;

@Service
@Transactional
public class MenuItemServiceImpl implements MenuItemService {

    @Autowired
    private MenuItemDao menuItemDao;


    /**
     * 添加菜品信息，如果输入的菜品信息不全或不符合要求，将抛出异常
     * 如果添加的是套餐，要求必须要关联到单品
     * @param menuItem 添加的菜品
     * @param sigleItemIds 关联的单品（如果是套餐的话）
     * @return 添加成功的菜品id
     */
    @Override
    public Long addMenuItem(MenuItem menuItem, long[] sigleItemIds) {
        //检查菜品信息
        if (!menuItem.checkAdditionInfoComplete()) {
            throw new SystemException("菜品信息不全或不符合要求");
        }
        //添加menuItem
        menuItemDao.insertSelective(menuItem);
        //如果这是一个套餐，还需要添加关联的菜品种类
        if (menuItem.isCombo()) {
            //检查关联单品信息
            if (!Utils.isEmpty(sigleItemIds)) {
                //查询需要关联的菜品
                List<MenuItem> singleItemConcerved = menuItemDao.selectByPrimaryKeys(sigleItemIds);
                if (!CollectionUtils.isEmpty(singleItemConcerved)) {
                    //获得菜品信息
                    List<Map<String, Long>> items = new ArrayList<>();
                    for (MenuItem x : singleItemConcerved) {
                        if (x.isCombo()) {
                            throw new SystemException("套餐不能关联套餐");
                        }
                        Map<String, Long> item = new HashMap<>();
                        item.put("comboId", menuItem.getId());
                        item.put("menu_item_id", x.getId());
                        items.add(item);
                    }
                    menuItemDao.insertComboToMenuItem(items);
                }
                throw new SystemException("套餐关联单品信息不能为空");
            }
            throw new SystemException("套餐关联单品信息不能为空");
        }
        return menuItem.getId();
    }


    @Override
    public void updateMenuItem(MenuItem menuItem) {
        //拒绝种类更新
        if (menuItem.getType() != null) {
            throw new SystemException("更新失败，指定后不再允许修改菜品种类");
        }
        if (menuItem.getId() == null) {
            throw new SystemException("更新失败，未指定需更新的菜品");
        }
        //不能更新套餐关联的菜品，直接更新menuItem
        menuItemDao.updateByPrimaryKeySelective(menuItem);
    }

    /**
     * 删除菜品信息， 如果删除的是套餐，把与单品的关联也删除，如果删除的是单品，若有套餐关联该单品，不允许删除
     * @param id 删除的菜品id
     */
    @Override
    public void removeMenuItem(Long id) {
        //检查是否有建立了关联的套餐
        List<MenuItem> comboList = menuItemDao.selectComboBySingleItem(id);
        if (!CollectionUtils.isEmpty(comboList)) {
            throw new SystemException("删除失败，该单品正被套餐关联");
        }
        menuItemDao.deleteByPrimaryKey(id);
        menuItemDao.deleteComboToMenuItemByComboId(id);
    }

    @Override
    public List<MenuItem> listAllMenuItem() {
        //获取所有菜品的基本信息，套餐无需列出里面有什么
        List<MenuItem> menuItemList = menuItemDao.findAll();
        return menuItemList;
    }

    @Override
    public MenuItem getMenuItemById(Long id) {
        //根据菜品id查询相关详细信息，如果是套餐，需要列出有哪些单品
        MenuItem target = menuItemDao.selectByPrimaryKey(id);
        if (ObjectUtils.isEmpty(target)){
            return target;
        }
        if (Utils.isMenuItemCombo(target.getType())) {
            //获取关联单品详细信息
            List<MenuItem> singleItems = menuItemDao.selectByComboToMenuItemIds(id);
            //建立套餐与单品的联系
            Map<TypeNum, List<MenuItem>> comboContent = new HashMap<>();
            for (MenuItem singleItem : singleItems) {
                TypeNum type = singleItem.getType();
                if (!comboContent.containsKey(type)) {
                    comboContent.put(type, new ArrayList<>());
                }
                comboContent.get(type).add(singleItem);
            }
            target.setComboContent(comboContent);
        }
        return target;
    }

    @Override
    public List<MenuItem> getMenuItemsByType(TypeNum type) {
        List<MenuItem> target = menuItemDao.selectByType(type);
        return target;
    }
}

